package com.zhang.handler;

import cn.hutool.core.util.IdUtil;
import com.zhang.ClientChannelManage;
import com.zhang.HttpChannelManage;
import com.zhang.common.Constant;
import com.zhang.common.message.ProxyMessage;
import com.zhang.common.message.ProxyMessageUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 通知代理客户端 跟 真实服务器建立连接 handler 类
 * @author zhanghao
 */
public class HttpNotifyHandler extends ChannelInboundHandlerAdapter {

    /**
     * 获取http跟代理服务器的 通信id
     * @return
     */
    private static Long getHttpId(){
        return IdUtil.getSnowflake(1,1).nextId();
    }
    /**
     * 日志对象
     */
    static private Logger log = LoggerFactory.getLogger(HttpNotifyHandler.class);


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        Long httpId = HttpChannelManage.getHttpIdByChannel(ctx.channel());

        try{
            //读取消息头
            if(msg instanceof HttpRequest){

                HttpRequest request = (HttpRequest) msg;
                //查看是否存储此 http通道
                if (null != httpId){
                    ctx.fireChannelRead(msg);
                    return;
                }
                //域名
                String[] host = request.headers().get("Host").split(":");
                String shost = host[0];
                //浏览器跟代理服务器的channel上  绑定 浏览器请求的域名
                ctx.channel().attr(Constant.DOMAIN).set(shost);
                Channel channelByDomain = ClientChannelManage.getChannelByDomain(shost);
                if(null == channelByDomain){
                    log.error("代理客户端不存在");
                    return;
                }
                //不让通道自动读    -》  如果连接成功了  再转发请求


                ctx.channel().config().setAutoRead(false);

                httpId = getHttpId();
                //存储当前http channel
                HttpChannelManage.addIdAndChannel(httpId,ctx.channel());
                log.debug("让代理客户端去连接真实服务器");

                ProxyMessage proxyMessage = ProxyMessageUtil.buildConnectRealServerReq(httpId);
                channelByDomain.writeAndFlush(proxyMessage);
                //转发到
                log.debug("转发到下一个handle");
                ctx.fireChannelRead(msg);
                return;
            }
            //request 内容
            if(msg instanceof HttpContent){
                if(httpId != null){
                    ctx.fireChannelRead(msg);
                    return;
                }

                ReferenceCountUtil.release(msg);
                log.debug("需要先建立连接，丢弃");
                return;
            }
        }catch (Exception e){
            log.error("HttpNotifyHandler发生异常 error = {}",e);
        }
    }
}
